/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.treeeditpart;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.gef.ui.actions.RedoAction;
import org.eclipse.gef.ui.actions.UndoAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.dialogs.ResourceListSelectionDialog;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Region;
import org.eclipse.uml2.uml.StateMachine;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.IPapyrusUIConstants;
import com.cea.papyrus.core.actions.ApplyStereotypeAction;
import com.cea.papyrus.core.actions.CloseDiagramAction;
import com.cea.papyrus.core.actions.OpenDiagramAction;
import com.cea.papyrus.core.actions.delete.DeleteFromModelAction;
import com.cea.papyrus.core.actions.imports.ImportLibraryFromRepositoryAction;
import com.cea.papyrus.core.actions.imports.ImportPackageFromCurrentModelAction;
import com.cea.papyrus.core.actions.imports.ImportPackageFromFileAction;
import com.cea.papyrus.core.actions.imports.ImportPackageFromWorkspaceAction;
import com.cea.papyrus.core.actions.imports.ImportProfilesAsLibraryFromRepositoryAction;
import com.cea.papyrus.core.actions.profile.DisplayDefinitionHistoryAction;
import com.cea.papyrus.core.actions.selectcopypaste.CopyAction;
import com.cea.papyrus.core.actions.selectcopypaste.PapyrusSelectionAction;
import com.cea.papyrus.core.actions.selectcopypaste.PasteAction;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.treeeditpart.diagramview.DiagramItemEditPart;
import com.cea.papyrus.core.ui.dialogs.ChooseImportElementDialog;
import com.cea.papyrus.core.ui.dialogs.ChooseSetMetaclassDialog;
import com.cea.papyrus.core.ui.dialogs.ElementImportTreeSelectionDialog;
import com.cea.papyrus.core.ui.dialogs.PapyrusMessageDialog;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.core.utils.PapyrusUMLValidator;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.profile.ImageManager;

/**
 * Provides context menu actions for the Editor.
 */
//Darpan - made it public
public class TreeContextMenuProvider extends ContextMenuProvider {

	/**
	 * The editor's action registry.
	 */
	private ActionRegistry actionRegistry;

	/**
	 * debug channel.
	 */
	private static final int channel = 17;

	/**
	 * 
	 */
	private Action createClassDiagramAction;
	// private Action copy;
	// private Action paste;

	/**
	 * 
	 */
	private Action createCompositeDiagramAction;

	/**
	 * 
	 */
	private Action createStateMachineDiagramAction;

	/**
	 * 
	 */
	private Action createUseCaseDiagramAction;

	/**
	 * 
	 */
	private Action createDeploymentDiagramAction;

	/**
	 * 
	 */
	private Action createActivityDiagramAction;

	/**
	 * 
	 */
	private Action createComponentDiagramAction;

	/**
	 * 
	 */
	private Action createSequenceDiagramAction;

	/**
	 * 
	 */
	@SuppressWarnings("unused")
	private Action doubleClickAction;

	/**
	 * 
	 */
	private Action createProfile;

	/**
	 * 
	 */
	private Action addModel;

	/**
	 * 
	 */
	private Action addAllModel;

	/**
	 * 
	 */
	private Action addUMLModel;

	/**
	 * 
	 */
	private Action importElementFromFile;

	/**
	 * 
	 */
	private Action importElementFromProject;

	/**
	 * 
	 */
	private Action importElementFromWS;

	/**
	 * 
	 */
	private Action importMetaclass;

	/**
	 * 
	 */
	private Action validateProfileAction;

	/**
	 * 
	 */
	protected EditPartViewer viewer;

	/**
	 * 
	 */
	protected ModelManager modelManager;

	/**
	 * 
	 */
	protected final Package model;

	/**
	 * Instantiate a new menu context provider for the specified EditPartViewer and
	 * ActionRegistry.
	 * 
	 * @param viewer
	 *            the editor's graphical viewer
	 * @param modelManager
	 * @param registry
	 *            the editor's action registry
	 * @throws IllegalArgumentException
	 *             if registry is <tt>null</tt>.
	 */
	public TreeContextMenuProvider(EditPartViewer viewer, ActionRegistry registry,
			ModelManager modelManager) {
		super(viewer);
		if (registry == null) {
			throw new IllegalArgumentException();
		}
		actionRegistry = registry;
		this.viewer = viewer;
		this.modelManager = modelManager;
		this.model = modelManager.getTopPackageFromUMLResource();

		// actions
		// ******************************************validateProfileAction***************************************

		// copy = new Action() {
		// @Override
		// public void run() {
		// ISelection selection = getViewer().getSelection();
		//				
		// if(selection instanceof IStructuredSelection) {
		// Iterator it= ((IStructuredSelection)selection).iterator();
		// Collection umlElements = new ArrayList();
		// while(it.hasNext()) {
		// Object o = it.next();
		// if(o instanceof ElementTreeEditPart) {
		// umlElements.add(((ElementTreeEditPart)o).getUmlElement());
		// }
		// }
		//					
		// Command command= new CopyToClipboardCommand(umlElements);
		// LookForElement.getCommandStack().execute(command);
		// }
		// /*
		// Object e=((IStructuredSelection)selection).getFirstElement();
		// Element umlElement = (Element)((ElementTreeEditPart)e).getUmlElement();
		//		    	
		// Command command= new CopyToClipboardCommand(umlElement);
		// LookForElement.getCommandStack().execute(command);
		// */
		// // PapyrusMessageDialog.display("ok--> "+command, null);
		//				
		// }
		// };
		// copy.setText("copy");
		//		
		// paste = new Action() {
		// @Override
		// public void run() {
		// ISelection selection = getViewer().getSelection();
		// Object e=((IStructuredSelection)selection).getFirstElement();
		// Element umlElement = (Element)((ElementTreeEditPart)e).getUmlElement();
		//				
		// Command command= new PasteFromClipboardCommand(umlElement);
		// LookForElement.getCommandStack().execute(command);
		// // PapyrusMessageDialog.display("ok--> "+command, null);
		//				
		//				
		// }
		// };
		// paste.setText("paste");

		validateProfileAction = new Action() {
			@Override
			public void run() {
				ISelection selection = getViewer().getSelection();
				Object e = ((IStructuredSelection) selection).getFirstElement();
				Profile umlElement = (Profile) ((ElementTreeEditPart) e).getUmlElement();
				PapyrusUMLValidator validator = new PapyrusUMLValidator();

				boolean valid = validator.validatePapyrusUMLProfile(umlElement);

				if (!valid) {
					PapyrusMessageDialog.display(umlElement.getQualifiedName()
							+ " profile is ill formed!\n\n" + validator.getErrors(), null);
				}

				else {
					PapyrusMessageDialog.display(umlElement.getQualifiedName()
							+ " profile is valid.", null);
				}
			}
		};
		validateProfileAction.setText("validate profile");
		validateProfileAction.setToolTipText("profile validation");

		// ******************************************addDiagramAction***************************************
		// Create Diagrams
		createClassDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.CLASS_DIAGRAM);
		createClassDiagramAction.setText("Create a new Class Diagram");// this is a
		// tempory line.

		createCompositeDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.COMPOSITE_STRUCTURE_DIAGRAM);
		createCompositeDiagramAction.setText("Create a new Composite Diagram");// this is
		// a
		// tempory
		// line.

		createStateMachineDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.STATE_MACHINE_DIAGRAM);
		createStateMachineDiagramAction.setText("Create a new State Machine Diagram");// this
		// is a
		// tempory
		// line.

		createUseCaseDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.USE_CASE_DIAGRAM);
		createUseCaseDiagramAction.setText("Create a new Use Case Diagram");// this is a
		// tempory
		// line.

		createDeploymentDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.DEPLOYMENT_DIAGRAM);
		createDeploymentDiagramAction.setText("Create a new Deployment Diagram");// this
		// is a
		// tempory
		// line.

		createActivityDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.ACTIVITY_DIAGRAM);
		createActivityDiagramAction.setText("Create a new Activity Diagram");// this is
		// a
		// tempory
		// line.

		createComponentDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.COMPONENT_DIAGRAM);
		createComponentDiagramAction.setText("Create a new Component Diagram");// this is
		// a
		// tempory
		// line.
		createSequenceDiagramAction =
			new CreateElementAction(viewer, Diagram.class, modelManager,
					IPapyrusUIConstants.SEQUENCE_DIAGRAM);
		createSequenceDiagramAction.setText("Create a new Sequence Diagram");// this
		// is a
		// tempory
		// line.

		doubleClickAction = new Action() {

			@Override
			public void run() {

			}
		};

		// ImportAllModel Action
		addAllModel = new Action() {
			@Override
			public void run() {

			}
		};
		addAllModel.setText("Open all models of the project");
		addAllModel.setToolTipText("Open all models of the project");
		addAllModel.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(org.eclipse.ui.ISharedImages.IMG_TOOL_COPY));

		// ******************* importModel Action************************************
		addModel = new Action() {
			@Override
			public void run() {

			}
		};
		addModel.setText("Open model from the project");
		addModel.setToolTipText("Open model from the project");
		addModel.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
				org.eclipse.ui.ISharedImages.IMG_TOOL_NEW_WIZARD));

		// ******************* importUMLModel Action************************************
		addUMLModel = new Action() {
			@Override
			public void run() {

			}
		};
		addUMLModel.setText("Open UML file from the project");
		addUMLModel.setToolTipText("Open UML file from the project");
		addUMLModel.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(org.eclipse.ui.ISharedImages.IMG_TOOL_NEW_WIZARD));

		// ******************* createProfile Action************************************

		createProfile = new Action() {
			@Override
			public void run() {

			}
		};
		createProfile.setText("Create a profile");
		createProfile.setToolTipText("Create a profile");

		// ************************ Import element from project
		// ************************************************
		importElementFromProject = new Action() {
			@Override
			public void run() {
				ISelection selection = getViewer().getSelection();
				Object e = ((IStructuredSelection) selection).getFirstElement();
				org.eclipse.uml2.uml.Package umlpackage =
					(org.eclipse.uml2.uml.Package) ((ElementTreeEditPart) e).getUmlElement();

				ChooseImportElementDialog cied =
					new ChooseImportElementDialog(PlatformUI.getWorkbench()
							.getActiveWorkbenchWindow().getShell(), umlpackage,
							getModelManager());
				cied.open();
			}
		};
		importElementFromProject.setText("Import from current model");
		importElementFromProject.setToolTipText("Import from current model");

		// ************************ Import element from file
		// ************************************************
		importElementFromFile = new Action() {
			@Override
			public void run() {
				ISelection selection = getViewer().getSelection();
				Object e = ((IStructuredSelection) selection).getFirstElement();
				org.eclipse.uml2.uml.Package umlpackage =
					(org.eclipse.uml2.uml.Package) ((ElementTreeEditPart) e).getUmlElement();

				FileDialog fd =
					new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
							.getShell());
				String[] filterExt = {
						"*.uml"
				};
				fd.setFilterExtensions(filterExt);
				String selectedFile = fd.open();

				if (selectedFile != null) {
					ResourceSet resourceSet = new ResourceSetImpl();
					URI modelUri = URI.createFileURI(selectedFile);
					Resource modelResource = resourceSet.getResource(modelUri, true);
					ElementImportTreeSelectionDialog eisd =
						new ElementImportTreeSelectionDialog(PlatformUI.getWorkbench()
								.getActiveWorkbenchWindow().getShell(),
								((Package) modelResource.getContents().get(0)));
					int ret = eisd.open();

					if (ret == Window.OK) {
						ArrayList result = eisd.getResult();
						Iterator resultIter = result.iterator();
						while (resultIter.hasNext()) {
							Element element = (Element) resultIter.next();
							ElementImport ei = UMLFactory.eINSTANCE.createElementImport();
							ei.setImportedElement((PackageableElement) element);
							ei.setAlias(((NamedElement) element).getName());
							umlpackage.getElementImports().add(ei);
						}
					}
				}
			}
		};

		importElementFromFile.setText("Import from file");
		importElementFromFile.setToolTipText("Import from file");

		// ************************ Import element from workspace
		// ************************************************
		importElementFromWS = new Action() {
			@Override
			public void run() {
				ISelection selection = getViewer().getSelection();
				Object e = ((IStructuredSelection) selection).getFirstElement();
				org.eclipse.uml2.uml.Package umlpackage =
					(org.eclipse.uml2.uml.Package) ((ElementTreeEditPart) e).getUmlElement();

				ResourceListSelectionDialog wsDialog =
					new ResourceListSelectionDialog(PlatformUI.getWorkbench()
							.getActiveWorkbenchWindow().getShell(), ResourcesPlugin
							.getWorkspace().getRoot(), IResource.FILE);
				wsDialog.setTitle("Import Element From Workspace");
				int selectedResource = wsDialog.open();

				if (selectedResource == Window.OK) {
					ResourceSet resourceSet = new ResourceSetImpl();
					IFile selectedFile = (IFile) wsDialog.getResult()[0];
					URI modelUri =
						URI.createURI("platform:/resource"
								+ selectedFile.getFullPath().toString());
					Resource modelResource = resourceSet.getResource(modelUri, true);
					ElementImportTreeSelectionDialog eisd =
						new ElementImportTreeSelectionDialog(PlatformUI.getWorkbench()
								.getActiveWorkbenchWindow().getShell(),
								((Package) modelResource.getContents().get(0)));
					int ret = eisd.open();

					if (ret == Window.OK) {
						ArrayList result = eisd.getResult();
						Iterator resultIter = result.iterator();
						while (resultIter.hasNext()) {
							Element element = (Element) resultIter.next();
							ElementImport ei = UMLFactory.eINSTANCE.createElementImport();
							ei.setImportedElement((PackageableElement) element);
							ei.setAlias(((NamedElement) element).getName());
							umlpackage.getElementImports().add(ei);
						}
					}
				}
			}
		};
		importElementFromWS.setText("Import from workspace");
		importElementFromWS.setToolTipText("Import from workspace");

		// ******************************* importMetaclass;***************
		importMetaclass = new Action() {
			@Override
			public void run() {
				ISelection selection = getViewer().getSelection();
				Object e = ((IStructuredSelection) selection).getFirstElement();
				org.eclipse.uml2.uml.Package umlpackage =
					(org.eclipse.uml2.uml.Package) ((ElementTreeEditPart) e).getUmlElement();
				if (umlpackage instanceof Profile) {

					// opening of a message box indicating profile application
					final Shell message =
						new Shell(new Shell(), SWT.APPLICATION_MODAL | SWT.SHELL_TRIM);
					message.setText("Metaclass Import");
					message.setImage(ImageManager.IMG_METACLASS);
					message.setSize(250, 100);

					final Label label = new Label(message, SWT.NONE);
					label.setText("Fetching metaclasses...");
					label.setBounds(20, 15, 150, 20);

					message.open();

					ChooseSetMetaclassDialog cmcd =
						new ChooseSetMetaclassDialog(PlatformUI.getWorkbench()
								.getActiveWorkbenchWindow().getShell(), ((Profile) umlpackage));
					cmcd.open();

					message.close();
				}
			}
		};
		importMetaclass.setText("Import Metaclass");
		importMetaclass.setToolTipText("Import MetaClass");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.action.MenuManager#dispose()
	 */
	@Override
	public void dispose() {
		viewer = null;
		// modelManager = null;
		actionRegistry = null;
		super.dispose();
	}

	/**
	 * @return
	 */
	@Override
	public EditPartViewer getViewer() {
		return this.viewer;
	}

	/**
	 * @return
	 */
	public ModelManager getModelManager() {
		return this.modelManager;
	}

	/**
	 * Called when the context menu is about to show. Actions, whose state is enabled,
	 * will appear in the context menu.
	 * 
	 * @param manager
	 * @see org.eclipse.gef.ContextMenuProvider#buildContextMenu(org.eclipse.jface.action.IMenuManager)
	 */
	@Override
	public void buildContextMenu(IMenuManager manager) {
		GEFActionConstants.addStandardActionGroups(manager);

		IAction action;
		ISelection selection = viewer.getSelection();

		Object e = ((IStructuredSelection) selection).getFirstElement();

		if (e instanceof CommonTreeEditPart) {
			CommonTreeEditPart editpart = (CommonTreeEditPart) e;
			Element element = null;

			// Prepare delete action
			action =
				getActionRegistry()
				.getAction(DeleteFromModelAction.DELETE_FROM_MODEL_ACTION_ID);
			((DeleteFromModelAction) action).setSelection(selection);

			if (e instanceof DiagramTreeEditPart||e instanceof DiagramItemEditPart) {
				manager.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
				// open action
				IAction diagramAction =
					getActionRegistry().getAction(OpenDiagramAction.OPEN_DIAGRAM_ACTION_ID);
				((OpenDiagramAction) diagramAction).setSelection(selection);
				manager.appendToGroup(GEFActionConstants.GROUP_EDIT, diagramAction);
				// close action
				diagramAction =
					getActionRegistry().getAction(CloseDiagramAction.CLOSE_DIAGRAM_ACTION_ID);
				((CloseDiagramAction) diagramAction).setSelection(selection);
				manager.appendToGroup(GEFActionConstants.GROUP_EDIT, diagramAction);

			} else if (editpart instanceof ElementTreeEditPart) {
				// UML element
				element = ((ElementTreeEditPart) editpart).getUmlElement();

				// Do not authorize deletion for :
				// root Model
				// root Profile
				// the last region of a state machine
				if (element instanceof Region) {
					StateMachine stateMachine = ((Region) element).getStateMachine();
					if ((stateMachine == null)
							|| ((stateMachine != null) && stateMachine.getRegions().size() > 1))
						manager.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
				} else if (!((element instanceof Package) && (modelManager
						.getTopPackageFromUMLResource().equals(element)))) {

					manager.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
				}


				// CM: Remove validate profile
				// if(element instanceof Profile){
				// manager.add(validateProfileAction);
				// }
			}


			if (element == null) {
				// nothing more to do
				return;
			}

			// MenuManager subMenuCreate;
			MenuManager subMenuCreate;
			MenuManager subMenuDiagram;
			MenuManager subMenuImportElement;
			MenuManager subMenuImportPackage;

			// ////////////////////////////////////
			// UNDO AND REDO in outline
			// ////////////////////////////////////

			// "Undo" Menu
			IAction undoAction = getActionRegistry().getAction(ActionFactory.UNDO.getId());
			if (undoAction instanceof UndoAction) {
				// action should be updated when outline is selected, but...
				((UndoAction) undoAction).update();
				manager.appendToGroup(GEFActionConstants.GROUP_UNDO, undoAction);
			}

			// "Redo" Menu
			IAction redoAction = getActionRegistry().getAction(ActionFactory.REDO.getId());
			if (redoAction instanceof RedoAction) {
				// action should be updated when outline is selected, but...
				((RedoAction) redoAction).update();
				manager.appendToGroup(GEFActionConstants.GROUP_UNDO, redoAction);
			}

			// "Copy" Menu
			IAction copyAction = getActionRegistry().getAction(ActionFactory.COPY.getId());
			if (copyAction instanceof CopyAction) {
				// action should be updated when outline is selected, but...
				((CopyAction) copyAction).update();
				manager.appendToGroup(GEFActionConstants.GROUP_COPY, copyAction);
			}

			IAction pasteAction = getActionRegistry().getAction(ActionFactory.PASTE.getId());
			if (pasteAction instanceof PasteAction) {
				// action should be updated when outline is selected, but...
				((PasteAction) pasteAction).update();
				manager.appendToGroup(GEFActionConstants.GROUP_COPY, pasteAction);
			}

			manager.add(new Separator("AddElement"));
			manager.add(new Separator("createDiagram"));
			manager.add(new Separator("subMenuImport"));

			// element != null
			subMenuCreate = new MenuManager("Add an element");

			// ////////////////////////////////////////////////////////
			// TEST CASE
			// ////////////////////////////////////////////////////////
			// for each create action in the registry, test if it works for this element
			Set<CreateElementActionWithCommand> enabledCreateActions =  
				new TreeSet<CreateElementActionWithCommand>(
						new Comparator<CreateElementActionWithCommand>() {
							public int compare(CreateElementActionWithCommand a, CreateElementActionWithCommand b) {
								String aText = a.getText(); 
								return (aText != null) ? aText.compareTo(b.getText()) : 1;
							}
						});
			Iterator<IAction> it = actionRegistry.getActions();
			while (it.hasNext()) {
				action = (IAction) it.next();
				if (action instanceof CreateElementActionWithCommand) {
					Debug.debug(this, "working with action " + action.getId(), channel);
					CreateElementActionWithCommand createAction = (CreateElementActionWithCommand) action;
					createAction.setSelection(selection);
					if (createAction.isEnabled()) {
						enabledCreateActions.add(createAction);
					}
				}
			}

			for (IAction a : enabledCreateActions) {
				subMenuCreate.add(a);
			}

			// import element submenu
			subMenuImportElement = new MenuManager("Import Element");
			if (element instanceof org.eclipse.uml2.uml.Package) {
				manager.appendToGroup("AddElement", subMenuImportElement);
				subMenuImportElement.add(importElementFromProject);
				subMenuImportElement.add(importElementFromFile);
				subMenuImportElement.add(importElementFromWS);
			}

			// import package submenu
			subMenuImportPackage = new MenuManager("Import Package");
			if (element instanceof org.eclipse.uml2.uml.Package) {
				manager.appendToGroup("AddElement", subMenuImportPackage);
				addActionInMenu(subMenuImportPackage, ImportPackageFromCurrentModelAction.IMPORT_PACKAGE_FROM_CURRENT_MODEL_ACTION_ID);
				addActionInMenu(subMenuImportPackage, ImportPackageFromFileAction.IMPORT_PACKAGE_FROM_FILE_ACTION_ID);
				addActionInMenu(subMenuImportPackage, ImportPackageFromWorkspaceAction.IMPORT_PACKAGE_FROM_WORKSPACE_ACTION_ID);
				addActionInMenu(subMenuImportPackage, ImportLibraryFromRepositoryAction.IMPORT_PACKAGE_FROM_LIBRARY_ACTION_ID);
				addActionInMenu(subMenuImportPackage, ImportProfilesAsLibraryFromRepositoryAction.IMPORT_PACKAGE_FROM_PROFILE_ACTION_ID);
			}

			if (element instanceof org.eclipse.uml2.uml.Profile) {
				subMenuImportElement.add(importMetaclass);
			}

			// submenu add diagram
			subMenuDiagram = new MenuManager("Add a diagram");
			subMenuDiagram.add(createClassDiagramAction);
			subMenuDiagram.add(createCompositeDiagramAction);
			subMenuDiagram.add(createUseCaseDiagramAction);
			subMenuDiagram.add(createDeploymentDiagramAction);
			subMenuDiagram.add(createComponentDiagramAction);
			if (element instanceof org.eclipse.uml2.uml.BehavioredClassifier) {
				subMenuDiagram.add(createStateMachineDiagramAction);
			}
			if ((element instanceof org.eclipse.uml2.uml.BehavioredClassifier)
					|| (element instanceof org.eclipse.uml2.uml.BehavioralFeature)) {
				subMenuDiagram.add(createActivityDiagramAction);
			}
			if ((element instanceof BehavioredClassifier || element instanceof Package)) {
				// Disallow multiple diagrams for one interaction because
				// SeDi is constructed to closely reflect the UML model.
				// if (!SeDiPapyrusInterchange.containsSequenceDiagram(element))
				subMenuDiagram.add(createSequenceDiagramAction);
			}
			manager.appendToGroup("AddElement", subMenuCreate);
			manager.appendToGroup("createDiagram", subMenuDiagram);

			// Profile management Actions
			MenuManager subMenuProfile = new MenuManager("Profile");
			action = getActionRegistry().getAction(ApplyStereotypeAction.APPLY_STEREOTYPE_ACTION_ID);
			if (action.isEnabled()) {
				subMenuProfile.add(action);
			}
			if (element instanceof org.eclipse.uml2.uml.Profile) {
				if(((Profile)element).getOwner()==null) {
					addActionInMenu(subMenuProfile, DisplayDefinitionHistoryAction.DISPLAY_DEFINITION_HISTORY_ID);
				}
			}

			if (!subMenuProfile.isEmpty()) {
				manager.appendToGroup(GEFActionConstants.GROUP_REST, subMenuProfile);
			}

			manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

		}
	}
	
	/**
	 * Adds an action into a specified menu, given its action ID
	 * @param menuManager the menu that displays the action
	 * @param actionID Id of the action to display
	 */
	protected void addActionInMenu(MenuManager menuManager, String actionID) {
		IAction action = getActionRegistry().getAction(actionID);
		if(action!=null) {
			((PapyrusSelectionAction)action).setSelection(viewer.getSelection());
			menuManager.add(action);
		}
	}

	/**
	 * @return
	 */
	private ActionRegistry getActionRegistry() {
		return actionRegistry;
	}

}
